package com.gitee.wsl.platform.network

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.withContext
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.NetworkInterface

actual suspend fun NetworkChecker.getInfo(): ConnectionInfo? = withContext(Dispatchers.IO) {
    val networkConnection = getNetworkStatus()
    if(!networkConnection.isConnected) return@withContext null
    val networkType = networkConnection.networkType
    try {
        //debugLog("getIpInfo networkConnection = $networkConnection")

        var ipv4: String? = null
        var ipv6: String? = null

        for (networkInterface in NetworkInterface.getNetworkInterfaces()) {
            //debugLog("getIpInfo networkInterface = $networkInterface")
            if (
                networkInterface.isUp &&
                ((networkType == NetworkType.WIFI && networkInterface.name.startsWith("wlan")) ||
                        (networkType == NetworkType.CELLULAR && networkInterface.name.startsWith("rmnet")) ||
                        (networkType == NetworkType.ETHERNET && networkInterface.name.startsWith("eth")) ||
                        (networkType == NetworkType.BLUETOOTH_TETHERING && networkInterface.name.startsWith("bt")) ||
                        (networkType == NetworkType.UNKNOWN && networkInterface.name.startsWith("ap")) ||
                        (networkType == NetworkType.UNKNOWN && networkInterface.name.startsWith("p2p")) ||
                        (networkType == NetworkType.UNKNOWN && networkInterface.name.startsWith("tun")) ||
                        (networkType == NetworkType.UNKNOWN && networkInterface.name.startsWith("ppp")) ||
                        (networkType == NetworkType.UNKNOWN && networkInterface.name.startsWith("wigig")) ||
                        (networkType == NetworkType.UNKNOWN && networkInterface.name.startsWith("fxa")))
            ) {
                //debugLog("getIpAddress networkConnectionInterface = $networkInterface")
                val inetAddresses = networkInterface.inetAddresses

                while (inetAddresses.hasMoreElements()) {
                    val inetAddress = inetAddresses.nextElement()
                    //debugLog("getIpAddress inetAddress = $inetAddress")
                    if (!inetAddress.isLoopbackAddress) {
                        if (ipv4 == null && inetAddress is Inet4Address) ipv4 = inetAddress.hostAddress?.toString()
                        if (ipv6 == null && inetAddress is Inet6Address) ipv6 = inetAddress.hostAddress?.toString()
                    }
                }
            }
        }

        return@withContext ConnectionInfo(
            ipv4 = ipv4,
            ipv6 = ipv6,
            //externalIp = getExternalIp()
        )
    } catch (error: Exception) {
        ensureActive()
        //debugLog("getIpInfo networkConnection = $networkConnection", error)
        return@withContext null
    }
}